import {
  viewSuffix,
  controlSuffix,
  EVENT_CONFIG_MSG,
  EVENT_INTI_CONFIG,
  EVETN_CONTROL_CONFIG_MSG,
  EVENT_SCREEN_TO_CONFG,
} from "../constant";
import config from "../../../config";
import { event } from "./event";
import MqttClient from "../mqttClient";
import Strategy from "./strategy";
import { debound, getScreenInfo } from "./utils";
class CommunicationRemote extends Strategy {
  clientName = "mqtt";

  constructor(id, options) {
    MqttClient.createClient().then((client) => {
      this.client = client;
      options.onConnect && options.onConnect(this);
      this.onMessage();
    });
    super(id, options);
    if (!this.options.isControl) {
      window.addEventListener("resize", this.doPublishScreenOptions);
    }
    window.addEventListener("beforeunload", this.onBeforeunload);
  }

  onMessage() {
    this.isFirsetSendConfig = false;
    this.client.on("message", (topic, message) => {
      const data = JSON.parse(message);
      console.log(`from topic ${topic} form username ${data.username}`);

      if (topic === this.topicState) {
        this.towHandshake(data);
        return;
      }

      if (topic === this.topicMsg) {
        this.onConfig(data);
        return;
      }

      if (topic === this.topicScreen) {
        this.dispatch(EVENT_SCREEN_TO_CONFG, data);
        return;
      }

      if (topic === this.topicLeave) {
        console.log("离开事件");
        this.dispatchLevae(data.username);
      }

      if (topic === this.topicEnter) {
        this.pushUserName(data);
      }
    });
  }

  onConfig(data) {
    const { username, isControl } = data;
    // 首次配置初始化,一般为保留消息触发
    if (this.options.isControl && isControl && !this.isFirsetSendConfig) {
      this.dispatch(EVENT_INTI_CONFIG, {
        ...data,
        config: data.config || config,
      });
      this.isFirsetSendConfig = true;
      return;
    }
    if (username === this.username) return;
    // 是当前正在使用的控制端在发送消息时，就这样，同步消息。
    if (this.options.isControl && isControl) {
      this.dispatch(EVETN_CONTROL_CONFIG_MSG, { ...data });
      return;
    }

    this.dispatch(EVENT_CONFIG_MSG, data);
  }

  isSubscribeMsgSuccess = false;
  /**
   * 订阅消息主题
   */
  doSubscribe() {
    return new Promise((resolve, reject) => {
      if (this.isSubscribeMsgSuccess) return resolve();
      const { qos } = this.data.subscription;
      this.client.subscribe(this.topicMsg, { qos }, (error, res) => {
        if (error) {
          console.log("Subscribe to topics error", error);
          reject(error);
          return;
        }

        console.log(`配置主题订阅成功 ${this.topicMsg}`);
        this.isSubscribeMsgSuccess = true;
        resolve();
      });
      this.client.subscribe(this.topicScreen, { qos });
      this.client.subscribe(this.topicEnter, { qos });
      this.client.subscribe(this.topicLeave, { qos });
    });
  }

  // 断开连接
  destroyConnection() {
    MqttClient.destory();
  }
  /**
   * 发布消息
   * @param {} topic 主题
   * @param {} retain 是否保留信息
   * @param {} payload 消息内容
   */
  doPublish({ topic, payload, retain = true }) {
    return new Promise((resolve, reject) => {
      const { qos } = this.data.publish;
      const json = this.payloadWrap({ ...payload });
      this.client.publish(topic, json, { qos, retain }, (error) => {
        if (error) {
          return reject();
        }
        return resolve();
      });
    });
  }

  check(resolve) {
    this.resolve = resolve;
    console.log("this.client.subscribe-->", this.client);
    const { qos } = this.data.subscription;
    this.client.subscribe(this.topicState, { qos }, (error, res) => {
      if (error) {
        console.log("Subscribe to topics error", error);
        return;
      }
      this.handshake();
    });

    this.doSubscribe().then(() => {
      this.resolve(this);
    });
  }

  /**
   * 连接前握手准备
   */
  handshake() {
    this.doPublishState();
  }
  /**
   * 收到对方的消息在进行握手确认
   * @param {*} data
   */
  towHandshake(data) {
    const { username, toname, isControl } = data;
    if (data && typeof data === "object" && data.username === this.username) {
      return;
    }
    if (toname === this.username) {
      this.dispatchResolve(data);
      return;
    }

    if (this.includesUserName(username)) return;
    this.pushUserName({ username, isControl });

    // 只有放映端接收控制端的消息
    if (isControl && !this.options.isControl) {
      this.doPublishState({ toname: username }).then(() => {
        this.dispatchResolve(data);
      });
      return;
    }

    // 只有控制端接收放映端的消息
    if (!isControl && this.options.isControl) {
      this.doPublishState({ toname: username }).then(() => {
        this.dispatchResolve(data);
      });
      return;
    }

    if (isControl && this.options.isControl) {
      // console.log("同行打个招呼");
      this.doPublishState({ toname: username });
    }
  }

  /**
   * 控制端向放映端发送消息
   */
  doPublishConfig(config) {
    this.doPublish({
      topic: this.topicMsg,
      retain: true,
      payload: {
        id: this.id,
        isControl: this.options.isControl,
        username: this.username,
        time: Date.now(),
        config: config,
      },
    })
      .then(() => {
        this.iseSend = true;
      })
      .catch((error) => {
        console.log("error-->", error);
      });
  }

  doPublishState(payload = {}) {
    return this.doPublish({
      topic: this.topicState,
      retain: false,
      payload: {
        id: this.id,
        isControl: this.options.isControl,
        username: this.username,
        time: Date.now(),
        ...payload,
      },
    });
  }

  destroy() {
    this.leave().then(() => {
      setTimeout(() => this.destroyConnection(), 500);
      window.removeEventListener("resize", this.doPublishScreenOptions);
      window.removeEventListener("beforeunload", this.onBeforeunload);
    });
  }

  async dispatchResolve(data) {
    this.resolve(this);
    this.resolve.isExecute = true;

    // 一秒后果没有收到保留消息就发送默认的配置
    setTimeout(() => {
      if (!this.isFirsetSendConfig && this.options.isControl) {
        this.isFirsetSendConfig = true;

        this.dispatch(EVENT_INTI_CONFIG, {
          config,
          id: this.id,
          isControl: this.options.isControl,
          username: this.username,
          time: Date.now(),
        });
      }

      if (!this.firsetSendScreenOptionsUsername.includes(data.username) && !this.options.isControl) {
        this.doPublishScreenOptions();
        this.firsetSendScreenOptionsUsername.push(data.username);
      }
      this.pushUserName(data);
    }, 1000);
  }

  doPublishScreenOptions = debound(() => {
    const screenInfo = getScreenInfo();
    return this.doPublish({
      topic: this.topicScreen,
      retain: false,
      payload: {
        config: screenInfo,
      },
    });
  }, 500);

  leave() {
    return this.doPublish({
      topic: this.topicLeave,
      retain: false,
      payload: {},
    });
  }

  onBeforeunload = (event) => {
    this.leave();
    event.returnValue = "关闭提示";

    return "关闭提示";
  };
}

export default CommunicationRemote;
